iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0
自我挑戰組

Go語言自學挑戰系列 第 20

第二十一天:Goroutine 介紹(2):協程同步sync.WaitGroup

  • 分享至 

  • xImage
  •  

繼續深入研究Goroutine

在第二十天的範例中主執行序完成後,未執行完畢的goroutine會被釋放掉,

所以需要使用time.Sleep()讓主執行序暫停一下,

不過golang提供sync函式庫可以使用。

協程同步sync.WaitGroup

sync.WaitGroup是一個同步的工具,可以等待goroutine完成。

  • Add() :計數器,goroutine的數量。
  • Done():計數器完成,進行減-1。
  • Wait():主執行序阻塞,直到所有 goroutine 完成為止。

實作參考資料1的範例:

package main

import (
	"fmt"
	"sync"
)
func main() {
	var wg sync.WaitGroup
	wg.Add(2) //兩個goroutine
	go func() {
		count("oranges")
		wg.Done()
	}()
	go func() {
		count("apples")
		wg.Done()
	}()
	count("banana")
	wg.Wait()
}

func count(thing string) {
	for i := 0; i < 4; i++ {
		fmt.Printf("counting %s\n", thing)
	}
}

輸出結果:

counting banana
counting banana
counting banana
counting banana
counting apples
counting apples
counting apples
counting apples
counting oranges
counting oranges
counting oranges
counting oranges

注意事項:

如果Add()大於goroutine數量會發生Deadlock

範例如下:

package main

import (
	"fmt"
	"sync"
)
func main() {
	var wg sync.WaitGroup
	wg.Add(3) //改為3
	go func() {
		count("oranges")
		wg.Done()
	}()
	go func() {
		count("apples")
		wg.Done()
	}()
	count("banana")
	wg.Wait()
}

func count(thing string) {
	for i := 0; i < 4; i++ {
		fmt.Printf("counting %s\n", thing)
	}
}

執行後會出現fatal error: all goroutines are asleep - deadlock!

參考資料

  1. https://zetcode.com/golang/goroutine/
  2. https://blog.kennycoder.io/2020/12/18/Golang%E6%95%99%E5%AD%B8%E7%B3%BB%E5%88%97-%E4%BD%95%E8%AC%82WaitGroup-%E7%AD%89%E5%BE%85Goroutine%E7%9A%84%E5%A5%BD%E5%B9%AB%E6%89%8B/
  3. https://ithelp.ithome.com.tw/articles/10240892

上一篇
第二十天:Goroutine介紹(1)
下一篇
第二十二天:Goroutine 介紹(3)channels 探討
系列文
Go語言自學挑戰29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言